#pragma once
#include <unistd.h>
#include <thread>
#include <string>
#include <stdexcept>

#include "utils/common_macros.h"
#include "boost/asio.hpp"

class DiscoveryService {
public:
    enum class NotifyMethod {
        EVENTFD_NOTIFY,
        UNIX_SOCKET_NOTIFY,
        SHARED_MEMORY_NOTIFY,
    };

    explicit DiscoveryService(boost::asio::io_context& io_context, const std::string& service_name = "");
    ~DiscoveryService();

    void send_broadcast(const std::string& message);
    void set_interval(uint64_t interval_s) { interval_ = interval_s; }

    void set_notify_method(NotifyMethod notify_method) {
        NOT_IMPLEMENTED();
    }

private:
    void handle_discovery_message(const std::string& message);

    void do_receive();
    void timer_to_send_broadcast();

    void timer_to_broadcast_pub_sub_infos();

    uint64_t interval_;
    std::array<char, 1024> buffer_;
    std::string service_name_;

    std::unordered_map<std::string, int> eventfd_map_;

    boost::asio::ip::udp::endpoint sender_endpoint_;
    boost::asio::io_context& io_context_;
    boost::asio::ip::udp::socket socket_;
    boost::asio::steady_timer timer_;
};
